package myJs.data.detailInfo

import com.softwaremill.quicklens._
import japgolly.scalajs.react.React.Fragment
import myJs.api.Api
import myJs.cps._
import myJs.tool.{Pojo, Tool}
import myJs.tool.Pojo._
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._
import shared.pojo.Data.DataInfo
import myJs.cps.BootstrapTableCp._
import myJs.Implicits._
import japgolly.scalajs.react._
import myJs.myPkg.Hooks._
import japgolly.scalajs.react.vdom.all._
import myJs.Utils._

import scala.scalajs.js.Dynamic.{global => g}
import scala.collection.immutable.SeqMap
import scala.scalajs.js

/** Created by yz on 3/11/2020
  */
object GeneCp {

  case class Props(symbol: String){
    @inline def render: VdomElement = {
      Component(this)
    }
  }

  val Component = ScalaFnComponent[Props] { props =>
    val (basicData, setBasicData) = useState(DataInfo())
    val (columns, setColumns) = useState(List.empty[Column])
    val (datas, setDatas) = useState(List.empty[ujson.Obj])

    object FTool {

      def refreshTableB = {
        Api.gene.allBySymbol(props.symbol).flatMapSync { response =>
          setDatas(response)
        }
      }

      def getColumns(infoMap: SeqMap[String, String]): List[Column] = {
        val map = infoMap
        val basicColumns = map.map { case (k, v) =>
          val searchKind = k match {
            case "frequency" | "publications" => NumericSearch
            case "variationType" | "clinicalSignificance" => CheckboxSearch
            case _ => TextSearch
          }
          val fmt = FTool.tbFmt(k)
          val comVF = FTool.comVFmt(k)
          val optionMap = searchKind match {
            case Pojo.CheckboxSearch => datas.map(_(k).myStr).distinct.sorted.optionMap
            case _ => SeqMap[String, String]()
          }
          Column(
            field = k,
            title = v,
            operable = true,
            searchKind = searchKind,
            formatter = fmt,
            comVF = comVF,
            optionMap = optionMap
          )
        }.toList
        basicColumns
      }

      def tbFmt(field: String) = (v: ujson.Value, row: ujson.Obj) => {
        val aStyle = TagMod(
          cursor.pointer
        )
        field match {
          case "name" =>
            val r = "(\\d+\\.\\d+\\.\\d+\\.\\d+)".r
            val rawHtml = r.replaceAllIn(
              v.myStr,
              replacer => {
                val id = replacer.group(1)
                val url = s"https://www.kegg.jp/entry/${id}"
                s"<a href = '${url}' target = '_blank' sytle='cursor:pointer'>${id}</a>"
              }
            )
            span(
              dangerouslySetInnerHtml := rawHtml
            )()
          case "pathway" =>
            val vs = v.arr.toList
            val rawHtml = vs
              .map { v =>
                val r = "(map\\d+)".r
              r.replaceAllIn(
                v.myStr,
                replacer => {
                  val id = replacer.group(1)
                  val url = s"https://www.kegg.jp/pathway/${id}+${row("entry").myStr}"
                  s"<a href = '${url}' target = '_blank' sytle='cursor:pointer'>${id}</a>"
                }
              )
              }
              .mkString("<br>")
            span(
              dangerouslySetInnerHtml := rawHtml
            )()
          case _ => span(FTool.comVFmt(field)(v, row))()
        }
      }

      def comVFmt(fileTitle: String) = (v: ujson.Value, row: ujson.Obj) => {
        fileTitle match {
          case _ => v.myStr
        }
      }

    }

    useEffect(
      {
        FTool.refreshTableB
      },
      List()
    )

    useEffect(
      {
        val map = Tool.geneMap
        val curColumns = FTool.getColumns(map)
        setColumns(curColumns)
      },
      List(datas)
    )

    Fragment(
      if (datas.nonEmpty) {
        Fragment(
          h4("Gene Info"),
          BootstrapTableCp.Props(
            columns = columns,
            datas = datas,
            pageList = List(10, 25, 50),
            pageSize = 10
          ).render
        )
      } else EmptyVdom
    )

  }

}
